/**
 * 
 */
package com.shine.icis.blo.imp;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;


import com.shine.cotrun.web.comm.SpringContextLoader;
import com.shine.cotrun.web.upload.FileDispatcher;
import com.shine.cotrun.web.upload.FileUtil;
import com.shine.icis.config.SysCodeDictLoader;
import com.shine.icis.config.SysConstants;
import com.shine.icis.blo.IDataSubmitService;
import com.shine.icis.blo.IETLLogService;
import com.shine.icis.blo.IFlowService;
import com.shine.icis.blo.IExpSubmitDataService;
import com.shine.icis.dao.IDataCheckDAO;
import com.shine.icis.dao.IDataSubmitDAO;
import com.shine.icis.dao.IETLContextVarDAO;
import com.shine.icis.dao.IETLLogDAO;
import com.shine.icis.dao.IMetadataCheckLogDAO;
import com.shine.icis.dao.ISubmitConfDAO;
import com.shine.icis.dao.ISubmitLogDAO;
import com.shine.icis.dto.DictOption;
import com.shine.icis.dto.ProgressStatus;
import com.shine.icis.dto.ReturnMsg;
import com.shine.icis.dto.SubmitConfig;
import com.shine.icis.dto.PfxBackInfo;
import com.shine.icis.exception.ICISException;
import com.shine.icis.hbean.DataCheckDef;
import com.shine.icis.hbean.ETLContextVar;
import com.shine.icis.hbean.ETLRunLog;
import com.shine.icis.hbean.FlowIns;
import com.shine.icis.hbean.FlowVar;
import com.shine.icis.hbean.ProgExeLog;
import com.shine.icis.hbean.ReportItem;
import com.shine.icis.hbean.SubmitLog;
import com.shine.icis.hbean.SubmitFile;
import com.shine.icis.hbean.SubmitReport;
import com.shine.icis.util.FTPHelper;
import com.shine.icis.util.ZipHelper;
/**
 * @author zsy
 *
 */
public class DataSubmitService implements IDataSubmitService {
	
	private IDataSubmitDAO dataSubmitDAO;
	private ISubmitConfDAO submitConfDAO;
	private ISubmitLogDAO submitLogDAO;
	private IETLLogDAO etlLogDAO;
	private IMetadataCheckLogDAO metadataCheckDAO;
	private IETLContextVarDAO etlContextVarDAO;
	private IDataCheckDAO dataCheckDAO;
	private IFlowService flowService;
	private IETLLogService etlLogService;
	
	private String copyTr12Path;
	
	private Map<String, String> sqlMap;//报送查询数据语句
//	private Map<String, String> dataProMap;//报送生表存储过程名称
	private Map<String, String> checkProMap;//报送生表存储过程名称
	
	public void setDataSubmitDAO(IDataSubmitDAO dataSubmitDAO) {
		this.dataSubmitDAO = dataSubmitDAO;
	}
	public void setSubmitConfDAO(ISubmitConfDAO submitConfDAO) {
		this.submitConfDAO = submitConfDAO;
	}
	public void setSubmitLogDAO(ISubmitLogDAO submitLogDAO) {
		this.submitLogDAO = submitLogDAO;
	}
	public void setEtlLogDAO(IETLLogDAO etlLogDAO) {
		this.etlLogDAO = etlLogDAO;
	}
	public void setMetadataCheckDAO(IMetadataCheckLogDAO metadataCheckDAO) {
		this.metadataCheckDAO = metadataCheckDAO;
	}
	public void setEtlContextVarDAO(IETLContextVarDAO etlContextVarDAO) {
		this.etlContextVarDAO = etlContextVarDAO;
	}
	public void setDataCheckDAO(IDataCheckDAO dataCheckDAO) {
		this.dataCheckDAO = dataCheckDAO;
	}
	
	public void setFlowService(IFlowService flowService) {
		this.flowService = flowService;
	}
	
	public void setEtlLogService(IETLLogService etlLogService) {
		this.etlLogService = etlLogService;
	}
	public void setCopyTr12Path(String copyTr12Path) {
		this.copyTr12Path = copyTr12Path;
	}
	public void setSqlMap(Map<String, String> sqlMap) {
		this.sqlMap = sqlMap;
	}

//	public void setDataProMap(Map<String, String> dataProMap) {
//		this.dataProMap = dataProMap;
//	}
	public void setCheckProMap(Map<String, String> checkProMap) {
		this.checkProMap = checkProMap;
	}
	
//	@Override
//	public void txCallProcs(boolean genData) throws ICISException {
//		if (dataProMap == null || checkProMap == null) {
//			throw new IllegalArgumentException();
//		}
//		
//		ProgressStatus pss =  getProgressStatus();
//		if (pss.getGenDataStatus() == -2 
//				 || pss.getGenDataStatus() == 0) {
//			throw new ICISException("数据还未采集完毕");
//		}
//		
//		ETLContextVar var = etlContextVarDAO.findByName("BUSI_DATE");
//		int busiDate = Integer.parseInt(var.getVarValue());
//		int beginDate = submitConfDAO.findPreviousTradeDate(busiDate);//存储过程参数，上一个交易日
//		var = etlContextVarDAO.findByName("INCREMENT");
//		
//		char runStatus = 0;
//		if (genData) {
//			try {
//				//记录过程日志与运行日志
//				etlLogService.ntxAddProgExeLog(ProgExeLog.ETL_TYPE_JOB, ProgExeLog.ETL_PROC_ID_GENDATA, ETLRunLog.RUN_STATUS_START);
//				etlLogService.ntxAddETLRunLog(ProgExeLog.ETL_PROC_ID_GENDATA, ETLRunLog.PREP_LEVEL_ID_INFO, ETLRunLog.RUN_STATUS_START, "手动开始生成报送数据");
//				for (String proc : dataProMap.values()) {
//					ReturnMsg msg = dataSubmitDAO.initSubmitTables(proc, beginDate, busiDate, var.getVarValue());
//					if(msg.getCode() == ReturnMsg.CODE_ERROR) {
//						etlLogService.ntxAddETLRunLog(ProgExeLog.ETL_PROC_ID_GENDATA, ETLRunLog.PREP_LEVEL_ID_ERROR, ETLRunLog.RUN_STATUS_FAILURE, msg.getText());
//					} else if (msg.getCode() == ReturnMsg.CODE_WARN) {
//						etlLogService.ntxAddETLRunLog(ProgExeLog.ETL_PROC_ID_GENDATA, ETLRunLog.PREP_LEVEL_ID_WARN, ETLRunLog.RUN_STATUS_SUCCESS, msg.getText());
//					}
//				}
//				runStatus = ETLRunLog.RUN_STATUS_SUCCESS;
//				//记录过程日志与运行日志
//				etlLogService.ntxAddETLRunLog(ProgExeLog.ETL_PROC_ID_GENDATA, ETLRunLog.PREP_LEVEL_ID_INFO, ETLRunLog.RUN_STATUS_SUCCESS, "手动生成报送数据成功");
//			} catch(RuntimeException e) {
//				//记录过程日志与运行日志
//				runStatus = ETLRunLog.RUN_STATUS_FAILURE;
//				etlLogService.ntxAddETLRunLog(ProgExeLog.ETL_PROC_ID_GENDATA, ETLRunLog.PREP_LEVEL_ID_ERROR, ETLRunLog.RUN_STATUS_FAILURE, "手动生成报送数据失败");
//				//生成数据与核对是一起做的，生成数据失败核对不做，则插入失败日志
//				etlLogService.ntxAddProgExeLog(ProgExeLog.ETL_TYPE_JOB, ProgExeLog.ETL_PROC_ID_DATACHECK, ETLRunLog.RUN_STATUS_START);//过程开始
//				etlLogService.ntxAddETLRunLog(ProgExeLog.ETL_PROC_ID_DATACHECK, ETLRunLog.PREP_LEVEL_ID_ERROR, ETLRunLog.RUN_STATUS_FAILURE, "手动核对报送数据失败，由于成报送数据失败");
//				etlLogService.ntxAddProgExeLog(ProgExeLog.ETL_TYPE_JOB, ProgExeLog.ETL_PROC_ID_DATACHECK, ETLRunLog.RUN_STATUS_FAILURE);//过程失败结束
//				throw e;
//			} finally {
//				etlLogService.ntxAddProgExeLog(ProgExeLog.ETL_TYPE_JOB, ProgExeLog.ETL_PROC_ID_GENDATA, runStatus);
//			}
// 		}
//
//		try {
//			//记录过程日志与运行日志
//			etlLogService.ntxAddProgExeLog(ProgExeLog.ETL_TYPE_JOB, ProgExeLog.ETL_PROC_ID_DATACHECK, ETLRunLog.RUN_STATUS_START);
//			etlLogService.ntxAddETLRunLog(ProgExeLog.ETL_PROC_ID_DATACHECK, ETLRunLog.PREP_LEVEL_ID_INFO, ETLRunLog.RUN_STATUS_START, "手动开始核对报送数据");
//			for (String proc : checkProMap.values()) {
//				ReturnMsg msg = dataSubmitDAO.initSubmitTables(proc, beginDate, busiDate, var.getVarValue());
//				if(msg.getCode() == ReturnMsg.CODE_ERROR) {
//					etlLogService.ntxAddETLRunLog(ProgExeLog.ETL_PROC_ID_DATACHECK, ETLRunLog.PREP_LEVEL_ID_ERROR, ETLRunLog.RUN_STATUS_FAILURE, msg.getText());
//				} else if (msg.getCode() == ReturnMsg.CODE_WARN) {
//					etlLogService.ntxAddETLRunLog(ProgExeLog.ETL_PROC_ID_DATACHECK, ETLRunLog.PREP_LEVEL_ID_WARN, ETLRunLog.RUN_STATUS_SUCCESS, msg.getText());
//				}
//			}
//			//记录过程日志与运行日志
//			runStatus = ETLRunLog.RUN_STATUS_SUCCESS;
//			etlLogService.ntxAddETLRunLog(ProgExeLog.ETL_PROC_ID_DATACHECK, ETLRunLog.PREP_LEVEL_ID_INFO, ETLRunLog.RUN_STATUS_SUCCESS, "手动核对报送数据成功");
//		} catch(RuntimeException e) {
//			//记录过程日志与运行日志
//			runStatus = ETLRunLog.RUN_STATUS_FAILURE;
//			etlLogService.ntxAddETLRunLog(ProgExeLog.ETL_PROC_ID_DATACHECK, ETLRunLog.PREP_LEVEL_ID_ERROR, ETLRunLog.RUN_STATUS_FAILURE, "手动核对报送数据失败");
//			throw e;
//		} finally {
//			etlLogService.ntxAddProgExeLog(ProgExeLog.ETL_TYPE_JOB, ProgExeLog.ETL_PROC_ID_DATACHECK, runStatus);
//		}
//	}
	
	@Override
	public void txCallCheckProc(String checkName, String checkDate) throws ICISException {
		if (checkProMap == null) {
			throw new IllegalArgumentException();
		}
//		String companyCode = submitConfDAO.findCompanyCode();
//		if (companyCode == null) {
//			throw new ICISException("请先配置证券公司基本信息");
//		}
		
		ProgressStatus pss =  getProgressStatus();
		if (pss.getDataCheckStatus() == -2 
				 || pss.getDataCheckStatus() == 0) {
			throw new ICISException("报送数据还未准备完毕");
		}
		//日志设定
		String logMsgStart;
		String logMsgOK;
		String logMsgError;
		if ("SE".equals(checkName)) {
			logMsgStart = "手动开始重新采集法人数据";
			logMsgOK    = "手动重新采集法人数据成功";
			logMsgError = "手动重新采集法人数据失败";
		} else if("A13_STD".equals(checkName)){
			logMsgStart = "手动开始重新生成A13标准层数据";
			logMsgOK    = "手动重新生成A13标准层数据成功";
			logMsgError = "手动重新生成A13标准层数据失败";
		} else if("A13_ANALYSE".equals(checkName)){
			logMsgStart = "手动开始重新生成A13应用层数据";
			logMsgOK    = "手动重新生成A13应用层数据成功";
			logMsgError = "手动重新生成A13应用层数据失败";
		} else {
			logMsgStart = "手动开始重新核对报送数据 " + checkName;
			logMsgOK    = "手动重新核对报送数据成功 " + checkName;
			logMsgError = "手动重新核对报送数据失败 " + checkName;
		}
		try {
			//记录运行日志
			etlLogService.ntxAddETLRunLog(ProgExeLog.ETL_PROC_ID_DATACHECK, ETLRunLog.PREP_LEVEL_ID_INFO, ETLRunLog.RUN_STATUS_START, logMsgStart);
			int busiDate;
			ETLContextVar var;
			if(checkDate != null && !checkDate.trim().equals("")){
				busiDate = Integer.parseInt(checkDate.trim().replaceAll("-", ""));
			} else {
				var = etlContextVarDAO.findByName("BUSI_DATE");
				busiDate = Integer.parseInt(var.getVarValue());
			}
			//ETLContextVar var = etlContextVarDAO.findByName("BUSI_DATE");
			int beginDate = submitConfDAO.findPreviousTradeDate(busiDate);//存储过程参数，上一个交易日
			var = etlContextVarDAO.findByName("INCREMENT");
			String proc = checkProMap.get("pro_" + checkName);
			ReturnMsg msg = dataSubmitDAO.initSubmitTables(proc, beginDate, busiDate, var.getVarValue());
			//记录运行日志
			if(msg.getCode() == ReturnMsg.CODE_ERROR) {
				etlLogService.ntxAddETLRunLog(ProgExeLog.ETL_PROC_ID_DATACHECK, ETLRunLog.PREP_LEVEL_ID_ERROR, ETLRunLog.RUN_STATUS_FAILURE, msg.getText());
			} else if (msg.getCode() == ReturnMsg.CODE_WARN) {
				etlLogService.ntxAddETLRunLog(ProgExeLog.ETL_PROC_ID_DATACHECK, ETLRunLog.PREP_LEVEL_ID_WARN, ETLRunLog.RUN_STATUS_SUCCESS, msg.getText());
			} else {
				etlLogService.ntxAddETLRunLog(ProgExeLog.ETL_PROC_ID_DATACHECK, ETLRunLog.PREP_LEVEL_ID_INFO, ETLRunLog.RUN_STATUS_SUCCESS, logMsgOK);
			}
		} catch(RuntimeException e) {
			//记录运行日志
			etlLogService.ntxAddETLRunLog(ProgExeLog.ETL_PROC_ID_DATACHECK, ETLRunLog.PREP_LEVEL_ID_ERROR, ETLRunLog.RUN_STATUS_FAILURE, logMsgError);
			throw e;
		}
	}
	
	@Override
	public SubmitLog txGeneratedFiles(String userCode, Boolean resubmitted, Boolean increVersion, Boolean copyTr12) throws Exception {
		ETLContextVar var = null;
		if (userCode == null) {//TASKSERVER调用
			var = etlContextVarDAO.findByName("OPERATOR");
			userCode =  var.getVarValue();
		} else {//WEB页面手工操作
			ProgressStatus pss =  getProgressStatus();
			if (pss.getGenFileStatus() == -2 
					 || pss.getGenFileStatus() == 0) {
				throw new ICISException("报送数据还未准备完毕");
			}
		}
		
		var = etlContextVarDAO.findByName("BUSI_DATE");
		String dataDate = var.getVarValue();
		var = etlContextVarDAO.findByName("INCREMENT");
		boolean increment = "1".equals(var.getVarValue());
		var = etlContextVarDAO.findByName("LOAD_TR12");
		boolean unLoadTr12 = "0".equals(var.getVarValue());//是否加载A01－A12
		
		if (resubmitted == null) {
//			var = etlContextVarDAO.findByName("RESUBMIT");
			resubmitted = false;
		}
		
		if (increVersion == null) {
			increVersion = resubmitted;//默认重报加版本
		}
		
		SubmitConfig cfg = loadSubmitConfig(dataDate, increVersion);//加载报送配置
		if (copyTr12 == null) {
			copyTr12 = cfg.isCopyTr12();//默认从配置读
		}
		
		File dir = null;//备份保存目录
		//生成到固定目录
		StringBuffer dirName = new StringBuffer(SysConstants.SUBMIT_FILES_DIR);
		dirName.append(dataDate).append("_");
		dirName.append(cfg.getGenerateCount());
		String dirPath = FileDispatcher.getSaveDir(FileDispatcher.getAbsPath(dirName.toString()));
		dir = new File(dirPath);
		
		if(!dir.exists()) {
			dir.mkdirs();
		}
		//记录报送信息LOG
		SubmitLog subLog = new SubmitLog(cfg);
		subLog.setIncrement(increment);
		subLog.setResubmitted(resubmitted);
		subLog.setDataDate(dataDate);
		subLog.setOperator(userCode);
		Set<SubmitFile> submitFiles = new TreeSet<SubmitFile>(new Comparator<SubmitFile>(){
			@Override
			public int compare(SubmitFile o1, SubmitFile o2) {
				return o1.getFileName().compareTo(o2.getFileName());
			}
			
		});
		subLog.setSubmitFiles(submitFiles);
		
		//生成文件名
		StringBuffer fileNameSB = new StringBuffer("SC_");
		fileNameSB.append(cfg.getCompanyCode()).append("_");
		fileNameSB.append(dataDate).append("_");
		fileNameSB.append(cfg.getVersion()).append(resubmitted ? "Y" : "N");
		fileNameSB.append("_@fileCode_@increment").append(".TXT");
		String fileName = fileNameSB.toString();
		
		try {
			//记录过程日志与运行日志
			etlLogService.ntxAddProgExeLog(ProgExeLog.ETL_TYPE_JOB, ProgExeLog.ETL_PROC_ID_GENFILE, ETLRunLog.RUN_STATUS_START);
			etlLogService.ntxAddETLRunLog(ProgExeLog.ETL_PROC_ID_GENFILE, ETLRunLog.PREP_LEVEL_ID_INFO, ETLRunLog.RUN_STATUS_START, "开始生成报送文件");
		
			
			ThreadGroup sftGroup = new ThreadGroup("submitFileTreadGroup");//报送线程组
			List<ExportSubmitFileTask> tasks = new ArrayList<ExportSubmitFileTask>(13);
			int startNum = 1;
			if (cfg.isExportA13Only() || copyTr12 || unLoadTr12) {//方案三或从源目源拷A01-A12或不加载A01-A12，只导出A13
				startNum = 13;
			}
			for (int i = 13; i >= startNum; i--) {//是否只导出A13
				String fileCode = "A" + (i < 10 ? "0" : "") + i;
				//增量的都要做
				ExportSubmitFileTask task = new ExportSubmitFileTask(fileCode, dataDate, cfg, dir, true, fileName);
				new Thread(sftGroup, task, fileCode).start();//启动线程
				tasks.add(task);
				if (!increment) {//如果是全量，生成全量的
					task = new ExportSubmitFileTask(fileCode, dataDate, cfg, dir, false, fileName);
					new Thread(sftGroup, task, fileCode).start();//启动线程
					tasks.add(task);
				}
			}
			
			//每2秒监听，所有线程都结束时获取导出结果LOG
			while (true) {
				if (sftGroup.activeCount() == 0){//监听线程组没有活动线程
					sftGroup.destroy();
					for (ExportSubmitFileTask task : tasks) {
						submitFiles.add(task.submitFile);//获得线程执行后生成的LOG对象
					}
					break;
				}
				try {
					Thread.sleep(2000);
				} catch(Exception e) {
					e.printStackTrace();
				}
			}
			
			if (!cfg.isExportA13Only() && !unLoadTr12 && copyTr12) {//方案三不拷贝
				//从源目录拷贝A01-A12文件
				try {
					String copyPath = this.copyTr12Path.replaceAll("@busiDate", dataDate);
					if (copyPath.startsWith("/") || copyPath.startsWith("\\")) {//相对路径，要拼接配置的源文件存放路径
						copyPath = cfg.getSourceDir() + copyPath;
					}
					for (int i = 1; i <= 12; i++) { 
						String fileCode = "A" + (i < 10 ? "0" : "") + i;
						submitFiles.add(copyTr2(fileCode, dir, true, fileName,copyPath,".txt"));
						if (!increment) {//如果是全量，移动全量的
							submitFiles.add(copyTr2(fileCode, dir, false,fileName,copyPath,".txt"));
						}
					}
				} catch (Exception e) {
					throw new RuntimeException(e.getMessage());
				}
			}
			
			//保存报送LOG
			submitLogDAO.save(subLog);
			
			//启动审批单
			startSubmitReport(subLog, dirPath, fileName, unLoadTr12);
			
			//记录过程日志与运行日志
			etlLogService.ntxAddProgExeLog(ProgExeLog.ETL_TYPE_JOB, ProgExeLog.ETL_PROC_ID_GENFILE, ETLRunLog.RUN_STATUS_SUCCESS);
			etlLogService.ntxAddETLRunLog(ProgExeLog.ETL_PROC_ID_GENFILE, ETLRunLog.PREP_LEVEL_ID_INFO, ETLRunLog.RUN_STATUS_SUCCESS, "生成报送文件成功");
		} catch(Exception e) {
			//记录过程日志与运行日志
			etlLogService.ntxAddProgExeLog(ProgExeLog.ETL_TYPE_JOB, ProgExeLog.ETL_PROC_ID_GENFILE, ETLRunLog.RUN_STATUS_FAILURE);
			etlLogService.ntxAddETLRunLog(ProgExeLog.ETL_PROC_ID_GENFILE, ETLRunLog.PREP_LEVEL_ID_ERROR, ETLRunLog.RUN_STATUS_FAILURE, "生成报送文件失败:" + e.getMessage());
			throw e;
		} finally {
			//整个过程结束日志
			etlLogService.ntxAddProgExeLog(ProgExeLog.ETL_TYPE_PRO, null, ETLRunLog.RUN_STATUS_SUCCESS);
		}
		return subLog;
	}
	
	@Override
	public SubmitLog txSendFiles(String userCode) throws Exception {
		ETLContextVar var = null;
		if (userCode == null) {//TASKSERVER调用
			var = etlContextVarDAO.findByName("OPERATOR");
			userCode =  var.getVarValue();
		} else {//WEB页面手工操作
			ProgressStatus pss =  getProgressStatus();
			if (pss.getGenFileStatus() == -2 
					 || pss.getGenFileStatus() == 0) {
				throw new ICISException("报送数据还未准备完毕");
			}
		}
		
		var = etlContextVarDAO.findByName("BUSI_DATE");
		String dataDate = var.getVarValue();
		var = etlContextVarDAO.findByName("INCREMENT");
		boolean increment = "1".equals(var.getVarValue());
		
		SubmitLog subLog = submitLogDAO.findLast();
		
		//取得当前日期
		String currentDate = getCurrentDate();
		//生成文件名
		StringBuffer fileNameSB = new StringBuffer("SC_");
		fileNameSB.append(subLog.getCompanyCode()).append("_");
		fileNameSB.append(dataDate).append("_");
		fileNameSB.append(subLog.getInternalVersion()).append(subLog.isResubmitted() ? "Y" : "N");
		fileNameSB.append("_@fileCode_@increment").append("_YA.7Z");
		String fileName = fileNameSB.toString();
		String fileNameOk = fileName + ".rdy";
		
		try {
			//记录过程日志与运行日志
			etlLogService.ntxAddProgExeLog(ProgExeLog.ETL_TYPE_JOB, ProgExeLog.ETL_PROC_ID_GENFILE, ETLRunLog.RUN_STATUS_START);
			etlLogService.ntxAddETLRunLog(ProgExeLog.ETL_PROC_ID_GENFILE, ETLRunLog.PREP_LEVEL_ID_INFO, ETLRunLog.RUN_STATUS_START, "开始发送报送文件");

			
			//取得icis_out目录
			String savePath = SysCodeDictLoader.getInstance().getSubmitConfValue("FILE_SAVE_PATH");
			if (savePath == null) {
				throw new ICISException("请先配置生成文件保存路径");
			}
			
			//取得pfx path
			String pfxPath = SysCodeDictLoader.getInstance().getSubmitConfValue("PFX_PATH");
			if (pfxPath == null) {
				throw new ICISException("请先配置pfx路径");
			}
			
			try {
				if (savePath.endsWith("/") || savePath.endsWith("\\")) {
					savePath = savePath + dataDate;
				} else {
					savePath = savePath + "/" + dataDate;
				}
				
				if (pfxPath.endsWith("/") || pfxPath.endsWith("\\")) {
					pfxPath = pfxPath + currentDate + "/" + "send"  ;
				} else {
					pfxPath = pfxPath + "/" + currentDate + "/" + "send"  ;
				}
				File dir = new File(pfxPath);
				if(!dir.exists()) {
					dir.mkdirs();
				}
				//删除目录中的所有文件
				//FileUtil.delFiles(dir);
				
				for (int i = 1; i <= 13; i++) { 
					String fileCode = "A" + (i < 10 ? "0" : "") + i;
					copyTr2(fileCode, dir, true, fileName,savePath,".7z");
					if (!increment) {//如果是全量，移动全量的
						copyTr2(fileCode, dir, false,fileName,savePath,".7z");
					}
				}
				//copy key，list 文件
				copyIndexFile(pfxPath, savePath, ".key");
				copyIndexFile(pfxPath, savePath, ".list");
				//生成ok文件
				for (int i = 1; i <= 13; i++) { 
					String fileCode = "A" + (i < 10 ? "0" : "") + i;
					createOkFile(fileCode, dir, true, fileNameOk);
					if (!increment) {//如果是全量，移动全量的
						createOkFile(fileCode, dir, false,fileNameOk);
					}
				}
				createIndexOkFile(pfxPath, savePath, ".key");
				createIndexOkFile(pfxPath, savePath, ".list");
			} catch (Exception e) {
				throw new RuntimeException(e.getMessage());
			}
		
			//记录过程日志与运行日志
			etlLogService.ntxAddProgExeLog(ProgExeLog.ETL_TYPE_JOB, ProgExeLog.ETL_PROC_ID_GENFILE, ETLRunLog.RUN_STATUS_SUCCESS);
			etlLogService.ntxAddETLRunLog(ProgExeLog.ETL_PROC_ID_GENFILE, ETLRunLog.PREP_LEVEL_ID_INFO, ETLRunLog.RUN_STATUS_SUCCESS, "发送报送文件成功");
		} catch(Exception e) {
			//记录过程日志与运行日志
			etlLogService.ntxAddProgExeLog(ProgExeLog.ETL_TYPE_JOB, ProgExeLog.ETL_PROC_ID_GENFILE, ETLRunLog.RUN_STATUS_FAILURE);
			etlLogService.ntxAddETLRunLog(ProgExeLog.ETL_PROC_ID_GENFILE, ETLRunLog.PREP_LEVEL_ID_ERROR, ETLRunLog.RUN_STATUS_FAILURE, "发送报送文件失败:" + e.getMessage());
			throw e;
		} finally {
			//整个过程结束日志
			etlLogService.ntxAddProgExeLog(ProgExeLog.ETL_TYPE_PRO, null, ETLRunLog.RUN_STATUS_SUCCESS);
		}
		return subLog;
	}
	
	public String getCurrentDate(){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		String date = sdf.format(new Date());
		return date;
	}
	@Override
	public List<String> getPfxFileList(String pfxDir) throws Exception{
		List<String> pfxFileList = new ArrayList<String>();
		
		String pfxPath = SysCodeDictLoader.getInstance().getSubmitConfValue("PFX_PATH");
		if (pfxPath == null) {
			throw new ICISException("请先配置pfx路径");
		}
		
		try {
			String currentDate = getCurrentDate();
			if (pfxPath.endsWith("/") || pfxPath.endsWith("\\")) {
				pfxPath = pfxPath + currentDate + "/" + pfxDir  ;
			} else {
				pfxPath = pfxPath + "/" + currentDate + "/" + pfxDir  ;
			}
			
			File pfxFile = new File(pfxPath);
			
		    if (pfxFile != null) {
				File[] fs = pfxFile.listFiles();
				if(fs != null && fs.length >= 1){
				    for(File f : fs){
				    	pfxFileList.add(f.getName());
					}
				}
		    }
		}catch (Exception e) {
			throw new RuntimeException(e.getMessage());
		}
		return pfxFileList;
	}
	@Override
	public List<PfxBackInfo> getPfxBackInfo() throws Exception{
		List<PfxBackInfo> pfxBackInfoList = new ArrayList<PfxBackInfo>();
		
		String pfxPath = SysCodeDictLoader.getInstance().getSubmitConfValue("PFX_PATH");
		if (pfxPath == null) {
			throw new ICISException("请先配置pfx路径");
		}
		
		try {
			String currentDate = getCurrentDate();
			if (pfxPath.endsWith("/") || pfxPath.endsWith("\\")) {
				pfxPath = pfxPath + currentDate + "/" + "back"  ;
			} else {
				pfxPath = pfxPath + "/" + currentDate + "/" + "back"  ;
			}
			
			File pfxFile = new File(pfxPath);
			
		    if (pfxFile != null) {
				File[] fs = pfxFile.listFiles();
				if(fs != null && fs.length >= 1){
				    for(File f : fs){
				    	PfxBackInfo pfxBackInfo = new PfxBackInfo();
				    	String fullFileName = f.getName();
				    	String[] splitStr = fullFileName.split("@"); 
				    	//序列号
				    	pfxBackInfo.setFileSerialNo(splitStr[1]);
				    	//发送状态
				    	pfxBackInfo.setStatus(splitStr[2]);
				    	//发送机构
				    	pfxBackInfo.setDept(splitStr[3]);
				    	//上传日期
				    	pfxBackInfo.setFileUploadDate(splitStr[4]);
				    	//文件名
				    	pfxBackInfo.setFileName(splitStr[5]);
				    	//文件大小
				    	pfxBackInfo.setFileSize(f.length());
				    	//文件日期
				    	long timeStamp = f.lastModified();
				        SimpleDateFormat formatter = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss");
				        String tsForm = formatter.format(new Date(timeStamp)) ;
				    	pfxBackInfo.setFileDate(tsForm);
				    	
				    	pfxBackInfoList.add(pfxBackInfo);
					}
				}
		    }
		}catch (Exception e) {
			throw new RuntimeException(e.getMessage());
		}
		return pfxBackInfoList;
	}
	/**
	 * 查找报送配置信息
	 * @return
	 * @throws ICISException 
	 */
	private SubmitConfig loadSubmitConfig(String dataDate, boolean increVersion) throws ICISException {
		SubmitConfig cfg = new SubmitConfig();
		//从icis_submit_conf表加载
		String value = SysCodeDictLoader.getInstance().getSubmitConfValue("FILE_SAVE_PATH");
		if (value == null) {
			throw new ICISException("请先配置生成文件保存路径");
		}
		cfg.setSaveDir(value);
		
		value = SysCodeDictLoader.getInstance().getSubmitConfValue("SOURCE_FILE_PATH");
		if (value == null) {
			throw new ICISException("请先配置源文件存放路径");
		}
		cfg.setSourceDir(value);
		
		value = SysCodeDictLoader.getInstance().getSubmitConfValue("INTERFACE_VER");
		if (value == null) {
			throw new ICISException("请先配置接口规范版本信息版本号");
		}
		cfg.setInterfaceVersion(value);
		
		//从eb_analyse.icis_company_info表加载
		String companyCode = submitConfDAO.findCompanyCode(dataDate);
		if (companyCode == null) {
			throw new ICISException("证券公司基本信息无记录，不能生成文件");
		}
		cfg.setCompanyCode(companyCode);
		/*
		 * 文件版本号规则是：
		 * 1.固定长度为3位，从1开始计数（如：001）
		 * 2.当天多次发送时版本号累加，跨天重新计数
		 */
		
		String maxVer = submitLogDAO.findInternalVersion(dataDate);
		if (maxVer == null) {
			maxVer = "001";
		} else if (increVersion) {
			int tem = Integer.parseInt(maxVer) + 1;
			DecimalFormat intFormat = new DecimalFormat("000");
			maxVer = intFormat.format(tem % 100);
		}
		cfg.setVersion(maxVer);
		
		//生成次数
		cfg.setGenerateCount(submitLogDAO.findSubmitLogCount(dataDate) + 1);
		
		
		//只导出A13
		value = SysCodeDictLoader.getInstance().getSubmitConfValue("EXP_A13_ONLY");
		cfg.setExportA13Only(value != null && "1".equals(value));
		
		//只从源文件拷贝A01-A12
		value = SysCodeDictLoader.getInstance().getSubmitConfValue("EXP_FILE_TYPE");
		cfg.setCopyTr12(value != null && "1".equals(value));
		return cfg;
	}
	
	/**
	 * 启动审批单
	 * @param subLog
	 */
	private void startSubmitReport(SubmitLog subLog, String dirPath, String fileName, boolean unLoadTr12) throws Exception {
		SubmitReport sr = new SubmitReport();
		sr.setSubmitLogId(subLog.getId());
		
		Collection<DictOption> systems = SysCodeDictLoader.getInstance().getBizSystemOptions();//柜台系统列表
		
		//取得最后一次过程结束日志
		ProgExeLog lastEndProLog = etlLogDAO.findLastEndProcess();
		if (systems != null && !systems.isEmpty() 
				&& lastEndProLog != null) {//无日志，从没运行过
		
			int operDate = lastEndProLog.getOperDate();
			int operTime = lastEndProLog.getOperTime();
			//取得最后一次过程结束日志之前的开始日志
			ProgExeLog lastStartProLog = etlLogDAO.findLastStartProcess(operDate, operTime);
			if (lastStartProLog == null) {//无日志，日志记录规则不对
				return;
			}
			//统计结束与开始之间的告警信息
			int msgNum = etlLogDAO.findETLRunLogNum(null, lastStartProLog.getOperDate(), lastStartProLog.getOperTime(), operDate, operTime, ETLRunLog.PREP_LEVEL_ID_WARN);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			
			//数据核查点列表
			List<DataCheckDef> dcds = dataCheckDAO.findDataCheckDefs(DataCheckDef.ON);
			sr.setContent("系统于" + MainMonitorService.formatDate(lastStartProLog.getOperDate(), lastStartProLog.getOperTime()) 
					+ "至" + MainMonitorService.formatDate(operDate, operTime) 
					+ "完成数据采集以及采集过程的元数据质量检查、数据核对、生成文件，其中注意级别的告警信息" + msgNum 
					+ "条，流程正常执行。同时，完成" + dcds.size() + "个功能点的数据核对工作，并成功生成13个报送文件。详细情况请查看报告如下：");
			sr.setSubmitter(subLog.getOperator());
			sr.setSubmitTime(new Date());
			
			Set<ReportItem> ris = new HashSet<ReportItem>();
			sr.setReportItems(ris);
			
			StringBuffer content = new StringBuffer("系统于");
			for (DictOption sys : systems) {
				//找出任务的日志，每步有两条，一条开始一条结束
				List<ProgExeLog> jobLogs = etlLogDAO.findPELogsByDatasetTypeId(Integer.parseInt(sys.getKey()), lastStartProLog.getOperDate(), lastStartProLog.getOperTime(), operDate, operTime);		
				if (jobLogs == null || jobLogs.isEmpty()) {//无日志，未开始
					continue;
				}
				ProgExeLog s_log = jobLogs.get(0);
				ProgExeLog e_log = jobLogs.get(jobLogs.size() - 1);
				content.append(MainMonitorService.formatDate(e_log.getOperDate(), e_log.getOperTime()))
						.append("完成“").append(sys.getText()).append("”数据采集过程，");
				msgNum = etlLogDAO.findETLRunLogNum(Integer.parseInt(sys.getKey()), s_log.getOperDate(), 
						s_log.getOperTime(), e_log.getOperDate(), e_log.getOperTime(), ETLRunLog.PREP_LEVEL_ID_WARN);
				if (msgNum == 0) {
					content.append("无注意级别的告警信息。");
				} else {
					content.append("注意级别的告警信息").append(msgNum).append("条。");
				}
			}
			ReportItem ri = new ReportItem();
			ri.setTitle("数据采集过程");
			ri.setContent(content.toString());
			ri.setOrderCode(1);
			ris.add(ri);
			
			content = new StringBuffer();
			msgNum = metadataCheckDAO.findMetadataCheckLogNum(lastStartProLog.getOperDate(), lastStartProLog.getOperTime(), operDate, operTime, ETLRunLog.PREP_LEVEL_ID_WARN);
			if (msgNum == 0) {
				content.append("元数据检查情况正常。");
			} else {
				content.append("注意级别的告警信息").append(msgNum).append("条。");
			}
			ri = new ReportItem();
			ri.setTitle("元数据质量检查");
			ri.setContent(content.toString());
			ri.setOrderCode(2);
			ris.add(ri);
			
			List<ProgExeLog> jobLogs = etlLogDAO.findPELogsByEtlProcId(ProgExeLog.ETL_PROC_ID_GENDATA, lastStartProLog.getOperDate(), lastStartProLog.getOperTime(), operDate, operTime);
			if (jobLogs != null && !jobLogs.isEmpty()) {
				ProgExeLog e_log = jobLogs.get(jobLogs.size() - 1);
				ri = new ReportItem();
				ri.setTitle("报送数据生成");
				ri.setContent("系统于" + MainMonitorService.formatDate(e_log.getOperDate(), e_log.getOperTime()) +"生成报送数据。");
				ri.setOrderCode(3);
			}
			
			
			if (dcds != null && !dcds.isEmpty())  {
				content = new StringBuffer("系统完成");
				for (DataCheckDef dcd : dcds) {
					content.append("“").append(dcd.getCheckName()).append("”");
				}
				content.append(dcds.size()).append("个功能点的数据核对，请到“报送数据核对”模块查看核对结果。");
				ris.add(ri);
				ri.setTitle("报送数据核对");
				ri.setContent(content.toString());
				ri.setOrderCode(3);
				ris.add(ri);
			}
		
			ri = new ReportItem();
			ri.setTitle("报送文件生成");
			ri.setContent(sdf.format(subLog.getOperateTime()) + "生成报送文件；数据日期："
					+ subLog.getFormatDataDate()
					+ "；导出方式：" 
					+ (subLog.isIncrement() ? "增量" : "全量") 
					+ "；重报标识：" + (subLog.isResubmitted() ? "是（Y）" : "否（N）") 
					+ "；内部版本号为：" + subLog.getInternalVersion() 
					+ "；操作员：" + subLog.getOperatorName() + "。");
			ri.setOrderCode(4);
			ris.add(ri);
		}
		submitLogDAO.save(sr);
		//新建流程实例
		List<FlowVar> vars = new ArrayList<FlowVar>();
//		vars.add(new FlowVar(SysConstants.FLOW_VAR_SUBMITDIR, subLog.getSaveDir(), "报送目录"));//报送目录
//		vars.add(new FlowVar(SysConstants.FLOW_VAR_SUBMITDATE, subLog.getDataDate(), "报送日期"));//报送日期
		vars.add(new FlowVar(SysConstants.FLOW_VAR_SOURCEDIR, dirPath, "源文件保存目录"));//源文件保存目录
		vars.add(new FlowVar(SysConstants.FLOW_VAR_FILENAME, fileName, "生成文件名模板"));//生成文件名模板
		vars.add(new FlowVar(SysConstants.FLOW_VAR_INCREMENT, Boolean.toString(subLog.isIncrement()), "增量标志"));//增量标志
		vars.add(new FlowVar(SysConstants.FLOW_VAR_UNLOADTR12, Boolean.toString(unLoadTr12), "不加载A01-A12"));//增量标志
		FlowIns fi = flowService.txNewFlowIns(SysConstants.DATA_SUBMIE_FLOW_ID, vars);
		
		sr.setInsId(fi.getInsId());
		submitLogDAO.update(sr);
		
		//进入流程第一步
		flowService.txToNextNode(fi.getInsId(), true);
	}

	/**
	 * 导出文件任务
	 * @author zsy
	 *
	 */
	class ExportSubmitFileTask implements Runnable {
		
		private String fileCode;
		private String dataDate;
		private SubmitConfig cfg;
		private File dir;
		private boolean increment;
		private String fileName;
		
		SubmitFile submitFile;
	
		ExportSubmitFileTask(String fileCode, String dataDate, SubmitConfig cfg, File dir, boolean increment,
				String fileName) {
			this.fileCode = fileCode;
			this.dataDate = dataDate;
			this.cfg = cfg;
			this.dir = dir;
			this.increment = increment;
			this.fileName = fileName.replaceAll("@fileCode", fileCode).replaceAll("@increment", (increment ? "Z" : "Q"));
		}
	
		@Override
		public void run() {

			//生成文件名
//			StringBuffer fileName = new StringBuffer("SC_");
//			fileName.append(cfg.getCompanyCode()).append("_");
//			fileName.append(dataDate).append("_");
//			fileName.append(cfg.getVersion()).append(resubmitted ? "Y" : "N").append("_");
//			fileName.append(fileCode).append("_");
//			fileName.append(increment ? "Z" : "Q").append(".TXT");
			
			//写入文件
			BufferedWriter fw = null;
			try {
				
				File f = new File(dir, fileName);
				if (f.exists()) {
					f.delete();
				}
				f.createNewFile();
//				fw = new BufferedWriter(new FileWriter(f));
				fw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), "utf-8"));
				long count = 0;
				if (("A08".equals(fileCode) || "A09".equals(fileCode) || "A10".equals(fileCode) 
						|| "A11".equals(fileCode)) && !increment) {//A08到A11全量只要报空文件
					//生成空文件，只要头文件信息即可
					fw.write("Version=" + cfg.getInterfaceVersion() + "|RecordCount=" + count);
					fw.write(0x0A);
				} else {
					List<Object> params = new ArrayList<Object>();//查询条件
					params.add(dataDate);//数据日期
					if (("A04".equals(fileCode) || "A05".equals(fileCode) || "A06".equals(fileCode) 
							|| "A07".equals(fileCode))) {
						params.add(increment ? "1" : "0");//增全量
					}
					String sql = sqlMap.get("sql_" + fileCode);//SQL语句
					
					//新线程Spring Bean实例要重新取，否则取不到事务
					IExpSubmitDataService dataSubmitService = (IExpSubmitDataService)SpringContextLoader.getBean("expSubmitDataService");
					dataSubmitService.csInit(sql, params);//设置参数
					count = dataSubmitService.getSQLDataCount();//总记录数
					
					fw.write("Version=" + cfg.getInterfaceVersion() + "|RecordCount=" + count);
					fw.write(0x0A);
					if (count != 0) {
						dataSubmitService.csWriteToFile(fw);
					}
					
				}
				//记录日志
				submitFile = new SubmitFile();
				submitFile.setFileCode(fileCode);
				submitFile.setFileName(fileName);
				submitFile.setDataCount(count);
				submitFile.setBackPath(f.getPath());
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					fw.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	@Override
	public String getCurrentVersion() {
		ETLContextVar var = etlContextVarDAO.findByName("BUSI_DATE");
		String dataDate = var.getVarValue();
		String maxVer = submitLogDAO.findInternalVersion(dataDate);
		if (maxVer == null) {
			maxVer = "001";
		}
		return maxVer;
	}
	
	@Override
	public String getBusiDate() {
		ETLContextVar var = etlContextVarDAO.findByName("BUSI_DATE");
		StringBuffer date = new StringBuffer(var.getVarValue());
		date.insert(6, "-").insert(4, "-");
		return date.toString();
	}
	
	@Override
	public ProgressStatus getProgressStatus() {
		//-2未就绪；-1等待；0运行中；1结束；2结束但TS处于运行中;3结束但出错
		ProgressStatus proSta = new ProgressStatus();
		ETLContextVar var = etlContextVarDAO.findByName("RUNNING");
		int etlRunning = Integer.parseInt(var.getVarValue());
		if (etlRunning == -2) {//-2 or -1
			proSta.setDataColStatus(-2);
			proSta.setGenDataStatus(-2);
			proSta.setDataCheckStatus(-2);
			proSta.setGenFileStatus(-2);
			return  proSta;
		} else if (etlRunning == -1) {
			proSta.setDataColStatus(-1);
			proSta.setGenDataStatus(-2);
			proSta.setDataCheckStatus(-2);
			proSta.setGenFileStatus(-2);
			return  proSta;
		}
		
		ProgExeLog progLog = etlLogDAO.findLastStartProcess();//最后开始的一条
		if (progLog == null) {
			proSta.setDataColStatus(-2);
			proSta.setGenDataStatus(-2);
			proSta.setDataCheckStatus(-2);
			proSta.setGenFileStatus(-2);
			return  proSta;
		}
		int operDate = progLog.getOperDate();
		int operTime = progLog.getOperTime();
		
//		progLog = etlLogDAO.findLastEndProcess(operDate, operTime);//查找结束记录
//		if (progLog != null) {//有记录，说明已经结束
//			proSta.setDataColStatus(-2);
//			proSta.setGenDataStatus(-2);
//			proSta.setDataCheckStatus(-2);
//			proSta.setGenFileStatus(-2);
//			return  proSta;
//		}
		
		/*
		 * 分析数据采集状态
		 */
		int status = getCollectStatus(etlRunning, operDate, operTime);
		proSta.setDataColStatus(status);
		
		/*
		 * 分析生成数据状态
		 */
		if (proSta.getDataColStatus() <= 0) {//前步未结束
			status = -2;
		} else {//前步已结束
			status = getElseStepStatus(ProgExeLog.ETL_PROC_ID_GENDATA, etlRunning, operDate, operTime);
		}
		proSta.setGenDataStatus(status);
		/*
		 * 分析数据核查状态
		 */
		if (proSta.getGenDataStatus() <= 0//前步未结束
				|| proSta.getGenDataStatus() == 3 ) {//前步出错
			status = -2;
		} else {//前步已结束
			status = getElseStepStatus(ProgExeLog.ETL_PROC_ID_DATACHECK, etlRunning, operDate, operTime);
		}
		proSta.setDataCheckStatus(status);
		
		/*
		 * 分析生成文件状态
		 */
		if (proSta.getDataCheckStatus() <= 0//前步未结束
				|| proSta.getDataCheckStatus() == 3) {//前步出错
			status = -2;
		} else {//前步已结束
			status = getElseStepStatus(ProgExeLog.ETL_PROC_ID_GENFILE, etlRunning, operDate, operTime);
		}
		proSta.setGenFileStatus(status);
		return proSta;
	}
	
	/**
	 * 取得第一步采集状态
	 * @param etlRunning
	 * @param operDate
	 * @param operTime
	 * @return
	 */
	private int getCollectStatus(int etlRunning, int operDate, int operTime) {
		int status = -2;
		//取得抽取的控制日志
		List<ProgExeLog> progLogs = etlLogDAO.findProgExeLogs(ProgExeLog.ETL_PROC_ID_EXCRACT, operDate, operTime);
		if (progLogs == null || progLogs.isEmpty()) {//抽取的控制日志为空，还未开始
			return -1;
		} else {//不为空，说明至少已经开始
			status = 0;
		}
		//再判断是否结束
		progLogs = etlLogDAO.findProgExeLogs(ProgExeLog.ETL_PROC_ID_TRANSFORM, operDate, operTime);
		if (progLogs == null || progLogs.isEmpty()) {//转换的控制日志为空，运行中
			return status;
		}
		Set<Integer> bizSystemEnds = new HashSet<Integer>();//记录已结束的系统，除重复
		for (ProgExeLog pl : progLogs) {
			if (pl.getRunStatus() == ETLRunLog.RUN_STATUS_START) {
				continue;//忽略开始的
			}
			bizSystemEnds.add(pl.getDatasetTypeID());
		}
		if (bizSystemEnds.size() >= SysCodeDictLoader.getInstance().getBizSystemOptions().size()) {
			//所有系统都结束，采集过程才算结束
			status = etlRunning == 1 ? 2 : 1;//TS还处于运行中状态为2
		}
		return status;
	}
	
	/**
	 * 取得其它步骤状态
	 * @param etlProcId
	 * @param etlRunning
	 * @param operDate
	 * @param operTime
	 * @return
	 */
	private int getElseStepStatus(int etlProcId, int etlRunning, int operDate, int operTime) {
		int status = -2;
		//取得抽取的控制日志
		List<ProgExeLog> progLogs = etlLogDAO.findProgExeLogs(etlProcId, operDate, operTime);
		if (progLogs == null || progLogs.isEmpty()) {//控制日志为空，还未开始
			return -1;
		} else {//不为空，说明至少已经开始
			status = 0;
			ProgExeLog pl = progLogs.get(progLogs.size() - 1);
			if (pl.getRunStatus() == ETLRunLog.RUN_STATUS_START) {
				status = 0;
			} else if (pl.getRunStatus() == ETLRunLog.RUN_STATUS_FAILURE) {
				status = 3;
			} else {
				status = etlRunning == 1 ? 2 : 1;//TS还处于运行中状态为2
			}
		}
		return status;
	}
	
	/**
	 * 拷贝A01~A12
	 * @author zhangxr
	 * */
	private SubmitFile copyTr2(String fileCode, File dir, boolean increment,
			String fileName,String copyTr2Path, String suffix) throws Exception {
	    File targetFile = new File(copyTr2Path);
	    if (targetFile == null) {
	    	throw new Exception("临时文件夹里不存在");
	    }
		File[] fs = targetFile.listFiles();
		if(fs == null || fs.length < 1){
			throw new Exception("临时文件夹里不存在这些文件");
		}
//	    StringBuffer fileName = new StringBuffer("SC_");
//	    fileName.append(cfg.getCompanyCode()).append("_");
//		fileName.append(dataDate).append("_");
//		fileName.append(cfg.getVersion()).append(resubmitted ? "Y" : "N").append("_");
//		fileName.append(fileCode).append("_");
//	    fileName.append(increment ? "Z" : "Q").append(".TXT");
		String incFlag = (increment ? "Z" : "Q");
	    String fileName_ = fileName.replaceAll("@fileCode", fileCode).replaceAll("@increment", incFlag);
	    File f_ = new File(dir, fileName_);
	    boolean found = false;
	    for(File f : fs){
	    	if(f.getName().toLowerCase().endsWith(suffix)){
				if(f.getName().indexOf(fileCode + "_" + incFlag) != -1){
					FileUtil.copyFile(f, f_, 1024 * 100);
					found = true;
					break;
				}
	    	}
		}
	    if (!found) {
	    	throw new Exception(fileCode + "_" + incFlag +"文件不存在");
	    }
	    SubmitFile submitFile = new SubmitFile();
		submitFile.setFileCode(fileCode);
		submitFile.setFileName(fileName_);
		submitFile.setDataCount(-1);
		submitFile.setBackPath(f_.getPath());
		return submitFile;
		
	}
	/**
	 * 拷贝key,list
	 * @author zuohp
	 * */
	private void copyIndexFile(String targetDir, String srcDir, String suffix) throws Exception {
	    File targetFile = new File(srcDir);
		File[] fs = targetFile.listFiles();
		if(fs == null || fs.length < 1){
			throw new Exception("生成文件夹里不存在" + suffix + "文件");
		}
	    File f_ = null;
	    for(File f : fs){
	    	if(f.getName().toLowerCase().endsWith(suffix)){
	    		f_ = new File(targetDir, f.getName());
				FileUtil.copyFile(f, f_, 1024 * 100);
	    	}
		}
	}
	/**
	 * 生成ok文件
	 * @author zuohp
	 * */
	private void createOkFile(String fileCode, File dir, boolean increment,
			String fileName) throws Exception {
		String incFlag = (increment ? "Z" : "Q");
	    String fileName_ = fileName.replaceAll("@fileCode", fileCode).replaceAll("@increment", incFlag);
	    File f = new File(dir, fileName_);
	    if (f.exists()){
	    	throw new Exception(fileName_ + "文件已存在！");
	    }
	    if (!f.createNewFile()){
	    	throw new Exception(fileName_ + "文件创建失败！");
	    }
	}
	/**
	 * 生成key,list的ok文件
	 * @author zuohp
	 * */
	private void createIndexOkFile(String targetDir, String srcDir, String suffix) throws Exception {
		File targetFile = new File(srcDir);
		File[] fs = targetFile.listFiles();
		if(fs == null || fs.length < 1){
			throw new Exception("生成文件夹里不存在" + suffix + "文件");
		}
	    File f_ = null;
	    for(File f : fs){
	    	if(f.getName().toLowerCase().endsWith(suffix)){
	    		String fileName = f.getName() + ".rdy";
	    		f_ = new File(targetDir, fileName);
	    		if (!f_.createNewFile()){
	    	    	throw new Exception(fileName + "文件创建失败！");
	    	    }
	    	}
		}	}
	@Override
	public SubmitLog getLastSubmitLog() {
		SubmitLog sl = submitLogDAO.findLast();
		if (sl != null) {
			sl.getSubmitFiles().size();//手动加载
		}
		return sl;
	}
	
	@Override
	public String csCompressSubmitFiles() throws ICISException {
		SubmitLog log =  submitLogDAO.findLast();
		String savePath = log.getSaveDir();
		if (FTPHelper.isFtpPath(savePath)) {
			throw new ICISException("生成文件保存路径配置为FTP地址，请从FTP上下载");
		}
		String zipName = log.getDataDate() + ".zip";
		File dir = new File(savePath + "/" + log.getDataDate());
		File[] fs = dir.listFiles();
		if (fs == null) {
			throw new ICISException("WEB服务器上" + dir.getPath() + "目录已被删除，或有配置审批流程且审批未通过取不到文件。");
		}
		List<File> filePaths = Arrays.asList(fs);
		File temDir = new File(FileDispatcher.getTempDir());
		if (!temDir.exists()) {
			temDir.mkdirs();
		}
//		System.out.println(zipName + "...........");
//		System.out.println(FileDispatcher.getTempDir() + zipName);
		ZipHelper.compressFiles(filePaths, FileDispatcher.getTempDir() + zipName);
		return FileDispatcher.getTempAbsDir() + zipName;
	}
}
